package com.sinsz.c;

import com.sinsz.c.cache.RedisCache;
import com.sinsz.c.properties.MybatisYmlProperties;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * 关系型数据连接设置
 *
 * @author chenjianbo
 * @date 2017年11月13日15:41:05
 */
@Configuration
@AutoConfigureAfter(value = {BxfsMybatisDataSourceConfig.class})
@EnableTransactionManagement
public class BxfsMybatisAutoConfiguration implements TransactionManagementConfigurer {

    private final DataSource dataSource;

    public BxfsMybatisAutoConfiguration(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    /**
     * 读取配置文件依赖
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public PathMatchingResourcePatternResolver resourcePatternResolver() {
        return new PathMatchingResourcePatternResolver();
    }

    /**
     * mybatis工程配置
     * <p>
     *     SpringBootVFS.class解决springBoot解决读取不到别名问题
     * </p>
     * @return
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean() {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setVfs(SpringBootVFS.class);
        bean.setConfigLocation(
                MybatisYmlProperties.instance().getConfig(resourcePatternResolver())
        );
        bean.setMapperLocations(
                MybatisYmlProperties.instance().getMapperXml(resourcePatternResolver())
        );
        return bean;
    }

    /**
     * 注入redis对应的键
     * <p>
     *     RedisCache.redisTemplate 设置redis操作实例
     *     RedisCache.expTime       设置过期时间
     * </p>
     * @param objectTemplate
     */
    @Resource(name = "objectTemplate")
    public void setRedisCacheTemplate(RedisTemplate<String, Object> objectTemplate) {
        long expTime = 1000 * 60 * 60;
        RedisCache.redisTemplate(objectTemplate);
        RedisCache.expTime(expTime, expTime / 20);
    }

    /**
     * 设置事务管理
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        DataSourceTransactionManager manager = new DataSourceTransactionManager();
        manager.setDataSource(dataSource);
        manager.setRollbackOnCommitFailure(true);
        return manager;
    }

    /**
     * 配置默认事务
     * @return
     */
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return transactionManager();
    }

}